#include "pfwidget.h"
#include "dm/dmdef.h"

PfWidget::PfWidget(const XoverType &type, QWidget *parent)
    : AWidget{parent}
    , m_type{type}
{

    titleLabel = new ALabel(type == XoverType::Hpf ? tr(LABEL_HPF) : tr(LABEL_LPF), this);
    slider = new ASlider(this);
    freqLabel = new ALabel(tr(LABEL_FREQ), this);
    if (type == XoverType::Hpf) {
        freqSpinBox = new OffSpinBox(OffSpinBox::Min, nullptr, this);
    }
    else {
        freqSpinBox = new OffSpinBox(OffSpinBox::Max, nullptr, this);
    }

    typeLabel = new ALabel(tr(LABEL_TYPE), this);
    typeComboBox = new AComboBox(this);
    slopeLabel = new ALabel(tr(LABEL_SLOPE), this);
    slopeComboBox = new AComboBox(this);

    auto layout = new QGridLayout(this);

    layout->addWidget(titleLabel, 0, 0, 1, 2, Qt::AlignHCenter);
    layout->addWidget(slider, 1, 0, 1, 2, Qt::AlignHCenter);
    layout->addWidget(freqLabel, 2, 0, 2, 1, Qt::AlignRight);
    layout->addWidget(freqSpinBox, 2, 1, 2, 1);
    layout->addWidget(typeLabel, 4, 0, 2, 1, Qt::AlignRight);
    layout->addWidget(typeComboBox, 4, 1, 2, 1);
    layout->addWidget(slopeLabel, 6, 0, 2, 1, Qt::AlignRight);
    layout->addWidget(slopeComboBox, 6, 1, 2, 1);
    layout->setVerticalSpacing(15 * ratio());

    for (const auto &type : PF_TYPE) {
        typeComboBox->addItem(tr(type));
    }
    for (const auto &slope : PF_TYPE_SLOPE) {
        slopeComboBox->addItem(QString::number(slope) + tr(LABEL_DECIBEL_UINT));
    }

    slider->setRange(EQ_FREQUENCY_MIN, EQ_FREQUENCY_MAX);
    freqSpinBox->setRange(EQ_FREQUENCY_MIN, EQ_FREQUENCY_MAX);

    connect(slider, QOverload<int>::of(&QSlider::valueChanged), freqSpinBox, &QSpinBox::setValue);
    connect(freqSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), slider, &QSlider::setValue);

    connect(freqSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this, &PfWidget::emitStateChanged);
    connect(typeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PfWidget::emitStateChanged);
    connect(slopeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PfWidget::emitStateChanged);

}

Xover PfWidget::value() const
{
    return {m_type,
            static_cast<uint16_t>(freqSpinBox->value()),
            static_cast<PfType>(typeComboBox->currentIndex()),
            static_cast<Slope>(slopeComboBox->currentIndex())
    };
}

void PfWidget::set(const Xover &xover, bool init)
{
    if (xover.type == m_type) {
        blockMemberSignals(true);
        slider->setValue(xover.freq);
        freqSpinBox->setValue(xover.freq);
        typeComboBox->setCurrentIndex(static_cast<int>(xover.ftype));
        slopeComboBox->setCurrentIndex(static_cast<int>(xover.slope));
        blockMemberSignals(false);

        emit stateChanged(xover, init);
    }

}

void PfWidget::emitStateChanged()
{
    emit stateChanged(value(), false);
}

void PfWidget::blockMemberSignals(bool block)
{
    freqSpinBox->blockSignals(block);
    typeComboBox->blockSignals(block);
    slopeComboBox->blockSignals(block);
}
